package com.flyco.modules.oms.handle.impl;

import com.flyco.common.constant.StockConstant;
import com.flyco.common.util.IdUtil;
import com.flyco.common.util.RedisUtil;
import com.flyco.modules.jddj.vo.OmsJddjOrderVO;
import com.flyco.modules.oms.entity.*;
import com.flyco.modules.oms.handle.IThirdOrderHandle;
import com.flyco.modules.oms.vo.OmsOrderPage;
import com.flyco.modules.pms.mapper.PmsSkuStockMapper;
import com.flyco.modules.pms.vo.PmsProductSkuForOrderVO;
import com.flyco.modules.stm.vo.StmStockVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ThirdOrderHandleImpl implements IThirdOrderHandle {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private PmsSkuStockMapper pmsSkuStockMapper;


    @Override
    public OmsOrderPage generateStoreOrderWithJddj(OmsJddjOrderVO page, Long storeId) {
        OmsOrderPage order = new OmsOrderPage();
        order.setPartnerId(1000L);
        order.setId(page.getId());
        order.setStoreId(storeId);
        order.setOrderSn(page.getId());
        order.setMemberId(1L);
        order.setOutPartnerId(1000L);
        order.setOutStoreId(storeId);
        //order.setCreateTime(page.getOrderStartTime());
        order.setCreateTime(new Date());
        order.setPaymentTime(page.getOrderPurchaseTime());
        order.setTotalAmount(long2BigDecimal(page.getOrderTotalMoney()));

        //支付金额=用户付款金额-京东扣除的费用
        order.setPayAmount(getPayAmountByBalanceBill(page.getBalanceBillList()));
        order.setEffectiveAmount(order.getPayAmount());
        //order.setPayAmount(long2BigDecimal(page.getOrderBuyerPayableMoney()));
        //order.setEffectiveAmount(long2BigDecimal(page.getOrderBuyerPayableMoney()));

        //order.setFreightAmount(long2BigDecimal(page.getOrderReceivableFreight()));
        order.setFreightAmount(BigDecimal.ZERO);
        order.setPromotionAmount(long2BigDecimal(page.getOrderDiscountMoney()));
        order.setIntegrationAmount(long2BigDecimal(page.getPlatformPointsDeductionMoney()));
        order.setPayType("unionPay");
        order.setSourceType("admin");
        order.setSourceSystem("shop");
        order.setReturnStatus(0);
        order.setStatus(3);
        order.setProductStatus(4);
        order.setPayStatus(4);
        order.setCancelFlag(0);
        order.setSendType(4);
        order.setReceiverName("京东到家默认用户");
        order.setReceiverPhone("10000000000");
        order.setConfirmStatus(1);
        order.setCouponAmount(BigDecimal.ZERO);
        order.setRedbagAmount(BigDecimal.ZERO);
        List<OmsOrderItem> omsOrderItemList = new ArrayList<>();
        List<OmsOrderInvoice> omsOrderInvoiceList = new ArrayList<>();
        OmsOrderInvoice orderInvoice = new OmsOrderInvoice();
        orderInvoice.setOrderId(page.getId());
        orderInvoice.setInvoiceType("0");
        orderInvoice.setInvoiceTitle("个人");
        omsOrderInvoiceList.add(orderInvoice);
        order.setOmsOrderInvoiceList(omsOrderInvoiceList);
        List<String> barCodes = page.getProduct().stream().map(r->r.getUpcCode()).collect(Collectors.toList());
        List<PmsProductSkuForOrderVO> skuForOrderVOS = pmsSkuStockMapper.getProductSkuForOrderList(storeId, barCodes);
        Map<String, PmsProductSkuForOrderVO> skuCodeMap = skuForOrderVOS.stream().collect(Collectors.toMap(PmsProductSkuForOrderVO::getSkuCode, t -> t));
        for (OmsJddjOrderProduct item : page.getProduct()) {
            OmsOrderItem orderItem = new OmsOrderItem();
            orderItem.setOrderId(page.getId());
            orderItem.setOrderSn(page.getId());
            orderItem.setProductSkuCode(item.getUpcCode());
            orderItem.setProductName(item.getSkuName());
            orderItem.setProductPrice(long2BigDecimal(item.getSkuJdPrice()));
            orderItem.setTotalRealAmount(orderItem.getProductPrice().multiply(new BigDecimal(item.getSkuCount())));
            orderItem.setProductQuantity(item.getSkuCount());
            if (skuCodeMap.containsKey(item.getUpcCode())) {
                PmsProductSkuForOrderVO vo = skuCodeMap.get(item.getUpcCode());
                orderItem.setProductId(vo.getId());
                orderItem.setProductPic(vo.getPic());
                orderItem.setProductBrand(vo.getBrandName());
                orderItem.setProductSn(vo.getProductSn());
                orderItem.setProductSkuId(vo.getSkuId());
                orderItem.setProductCategoryId(vo.getProductCategoryId());
            }
            omsOrderItemList.add(orderItem);
        }
        //设置订单明细的实付金额
        setTotalRealAmount(omsOrderItemList,order.getPayAmount());
        order.setOmsOrderItemList(omsOrderItemList);
        return order;
    }

    /**
     * 获取实付金额
     * @param balanceBillList
     * @return
     */
    BigDecimal getPayAmountByBalanceBill(List<OmsJddjBalanceBill> balanceBillList){
        if(balanceBillList==null || balanceBillList.size()==0){
            throw new RuntimeException("关键数据项为空");
        }
        List<OmsJddjBalanceBill> balanceBills = balanceBillList.stream().map(one->{
            OmsJddjBalanceBill newBill = new OmsJddjBalanceBill();
            BeanUtils.copyProperties(one, newBill);
            return newBill;
        }).collect(Collectors.toList());

        /*for(OmsJddjBalanceBill one:balanceBillList){
            //货款对账单
            if(one.getBillOrderType()==5006){
                return one.getGoodsBill().add(one.getStoreFreightAmount()).setScale(2,RoundingMode.HALF_UP);
            }
        }*/

        for(OmsJddjBalanceBill one:balanceBills){
            if(one.getBillOrderType()==5006){
                if (one.getGoodsBill().compareTo(BigDecimal.ZERO) <= 0 && one.getFreightBill().compareTo(BigDecimal.ZERO) <= 0) {
                    one.setGoodsBill(one.getDueAmount().subtract(one.getCommission()).subtract(one.getPickupAmount()));
                }
            }
        }
        return getPayAmountByBalanceBillCalc(balanceBills);
    }

    BigDecimal getPayAmountByBalanceBillCalc(List<OmsJddjBalanceBill> balanceBillList){
        BigDecimal reduce = balanceBillList.stream().filter(q -> Objects.equals(q.getBillOrderType(), 5006))
                .map(one -> one.getGoodsBill().add(one.getStoreFreightAmount()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return reduce.setScale(2,RoundingMode.HALF_UP);
    }


    public static void main(String[] args) {
        ThirdOrderHandleImpl thirdOrderHandle = new ThirdOrderHandleImpl();
        List<OmsJddjBalanceBill> balanceBillList = new ArrayList<>();
        if(true){
            OmsJddjBalanceBill omsJddjBalanceBill = new OmsJddjBalanceBill();
            omsJddjBalanceBill.setBillOrderType(5006);
            omsJddjBalanceBill.setGoodsBill(new BigDecimal("67.00"));
            omsJddjBalanceBill.setStoreFreightAmount(new BigDecimal("0.00"));
            balanceBillList.add(omsJddjBalanceBill);
        }
        if(true){
            OmsJddjBalanceBill omsJddjBalanceBill = new OmsJddjBalanceBill();
            omsJddjBalanceBill.setBillOrderType(5006);
            omsJddjBalanceBill.setGoodsBill(new BigDecimal(0));
            omsJddjBalanceBill.setStoreFreightAmount(new BigDecimal("4.00"));
            balanceBillList.add(omsJddjBalanceBill);
        }
        if(true){
            OmsJddjBalanceBill omsJddjBalanceBill = new OmsJddjBalanceBill();
            omsJddjBalanceBill.setBillOrderType(5008);
            omsJddjBalanceBill.setGoodsBill(new BigDecimal(10));
            omsJddjBalanceBill.setStoreFreightAmount(new BigDecimal("0.00"));
            balanceBillList.add(omsJddjBalanceBill);
        }
        BigDecimal payAmountByBalanceBill = thirdOrderHandle.getPayAmountByBalanceBill(balanceBillList);
        System.out.println(payAmountByBalanceBill);
    }

    /**
     * 获取实付金额
     * @param orderBillList
     * @return
     */
    BigDecimal getPayAmount(List<OmsJddjOrderBill> orderBillList){
        if(orderBillList==null || orderBillList.size()==0){
            throw new RuntimeException("关键数据项为空");
        }
        long price1 = 0;
        long price2 = 0;
        for(OmsJddjOrderBill one:orderBillList){
            //货款对账单
            if(one.getBillOrderType()==5006){
                //应结金额 = 用户支付-京东扣除(goodsCommissionBill为负数)
                price1 = one.getGoodsBill() + one.getGoodsCommissionBill();
                //price1 = new BigDecimal(one.getGoodsBill() + one.getGoodsCommissionBill());
            }
            //市场费对账单
            else if(one.getBillOrderType()==5008 && one.getMarketSettlementStatus()==2){
                //返利
                price2 = one.getMarketBill();
                //price2 = new BigDecimal(one.getMarketBill()).multiply(new BigDecimal(0.94)).setScale(2,BigDecimal.ROUND_HALF_UP);
            }
        }
        return new BigDecimal(price1+price2).divide(new BigDecimal(100),2,RoundingMode.HALF_UP);
    }

    /**
     * 根据实付金额
     * @param omsOrderItemList
     * @param payAmount
     * @return
     */
    void setTotalRealAmount(List<OmsOrderItem>omsOrderItemList, BigDecimal payAmount){
        //计算商品原价总金额
        BigDecimal originalTotalAmount = omsOrderItemList.stream().map(q -> q.getProductPrice().multiply(new BigDecimal(q.getProductQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        int cnt = 1;
        //剩余的金额，用来赋值给最后一个商品，避免尾差
        BigDecimal surplusAmount = payAmount;
        //同一个商品的实付总金额
        BigDecimal totalRealAmount;
        for(OmsOrderItem orderItem : omsOrderItemList){
            if(cnt==omsOrderItemList.size()){
                totalRealAmount = surplusAmount;
            }else {
                //商品实付金额 = 商品金额 / 订单原始金额 * 订单实付金额
                BigDecimal productTotalPrice = orderItem.getProductPrice().multiply(new BigDecimal(orderItem.getProductQuantity()));
                totalRealAmount = productTotalPrice.multiply(payAmount).divide(originalTotalAmount,2, RoundingMode.HALF_UP);
                surplusAmount = surplusAmount.subtract(totalRealAmount).setScale(2, RoundingMode.HALF_UP);
            }
            cnt++;
            //给商品赋值
            orderItem.setTotalRealAmount(totalRealAmount);
            orderItem.setRealAmount(totalRealAmount.divide(new BigDecimal(orderItem.getProductQuantity()),2, RoundingMode.HALF_UP));
        }
    }

    @Override
    public List<StmStockVO> generateStockRecord(OmsOrderPage orderPage) {
        List<StmStockVO> outStockVOList = new ArrayList<>();
        orderPage.getOmsOrderItemList().forEach(item->{
            StmStockVO vo = BeanUtils.instantiateClass(StmStockVO.class);
            vo.setProductId(item.getProductId());
            vo.setProductSn(item.getProductSn());
            vo.setStockType(StockConstant.STOCK_TYPE_GOODS);
            vo.setProductQty(item.getProductQuantity());
            outStockVOList.add(vo);
        });
        return outStockVOList;
    }

    public static boolean isNumeric(String str) {
        return str.matches("-?[0-9]+.？[0-9]*");
    }

    public static BigDecimal long2BigDecimal(Long num) {
        return new BigDecimal(num).divide(new BigDecimal(100));
    }

    /**
     * 生成18位订单编号:8位日期+2位平台号码+2位支付方式+6位以上自增id
     */
    @Override
    public String generateOrderSn() {
        String date = new SimpleDateFormat("yyyyMMddHH").format(new Date());
        String key = "portal:orderId:" + date;
        long seq = redisUtil.incr(key, 1);
        if (seq == 1L) {
            seq = redisUtil.incr(key, (long) (Math.random() * 500000));
            redisUtil.expire(key, 3600 * 2L);
        }
        return "" + IdUtil.genId("yyMMddHH{s}{s}{s}{s}{s}{r}{s}7", seq, 6);
    }
}
